<template>
  <nut-form
    ref="formRef"
    class="su-form"
    :model-value="form"
    :disable="disabled"
    :labelPosition="opts.labelPosition"
    :starPosition="opts.starPosition"
  >
    <nut-form-item
      v-for="column in columnOption"
      :key="column.prop"
      :prop="column.prop"
      :label="getLabel(column.label, column.labelSuffix || opts.labelSuffix)"
      :rules="getRules(column)"
      :labelPosition="column.labelPosition || opts.labelPosition"
      :starPosition="column.starPosition || opts.starPosition"
      :labelWidth="column.labelWidth || opts.labelWidth"
      :labelAlign="column.labelAlign || opts.labelAlign"
      :errorMessageAlign="column.errorMessageAlign || opts.errorMessageAlign"
      :showErrorLine="column.showErrorLine || opts.showErrorLine"
      :showErrorMessage="column.showErrorMessage || opts.showErrorMessage"
      :required="!isEmpty(column.rules)"
    >
      <template #label v-if="getSlotName(column, 'label', $slots)">
        <slot
          :name="getSlotName(column, 'label')"
          :column="column"
          :value="form[column.prop]"
          :readonly="column.readonly || readonly"
          :disabled="column.disabled || disabled"
        ></slot>
      </template>
      <template #default>
        <slot
          v-if="getSlotName(column, '', $slots)"
          :name="getSlotName(column, '')"
          :column="column"
          :value="form[column.prop]"
          :readonly="column.readonly || readonly"
          :placeholder="getPlaceholder(column)"
          :disabled="column.disabled || disabled"
        ></slot>
        <form-temp
          v-else
          :ref="column.prop"
          :dic="column.dicData"
          :column="column"
          :readonly="column.readonly || readonly"
          :disabled="column.disabled || disabled"
          :placeholder="getPlaceholder(column)"
          v-model="form[column.prop]"
        >
          <template v-for="slot in getColumnSlotName(column, $slots)" #[slot]="scope">
            <slot v-bind="scope" :name="slot"></slot>
          </template>
        </form-temp>
      </template>
    </nut-form-item>
    <view class="su-form__menu">
      <slot name="menu-form"></slot>
    </view>
  </nut-form>
</template>

<script setup>
import { useVModel } from '@vueuse/core';
import { getSlotName, getLabel, getColumnSlotName, getRules, getPlaceholder } from '@/supreme/core';
import { isEmpty } from 'lodash-es';
import FormTemp from './temp.vue';
const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  },
  option: {
    type: Object,
    default: () => ({})
  },
  readonly: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  }
});
const emit = defineEmits(['update:modelValue', 'change', 'submit', 'reset']);
const { option } = props;
const formRef = ref();
const form = useVModel(props, 'modelValue', emit);
provide('formSafe', form);
const opts = computed(() => {
  return {
    labelSuffix: '：',
    labelPosition: 'left',
    starPosition: 'left',
    labelAlign: 'left',
    labelWidth: '140px',
    errorMessageAlign: 'left',
    showErrorLine: true,
    showErrorMessage: true,
    ...option
  };
});
const columnOption = computed(() => {
  return option.column || [];
});

function submit() {
  return new Promise((resolve, reject) => {
    formRef.value?.validate().then(({ valid, errors }) => {
      if (valid) {
        resolve(form.value);
      } else {
        reject(errors);
      }
    });
  });
}
function validate(prop) {
  return new Promise((resolve, reject) => {
    formRef.value?.validate(prop).then(({ valid, errors }) => {
      if (valid) {
        resolve(form.value);
      } else {
        reject(errors);
      }
    });
  });
}
function reset() {
  formRef.value?.reset();
}
defineExpose({
  formRef,
  form,
  submit,
  validate,
  reset
});
</script>

<style lang="scss">
.su-form {
  &__menu {
    @include wh(100%);
    padding: 30px 20px 0;
  }
}
</style>
